package app.gui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.ScrollPaneConstants;
import javax.swing.SpinnerListModel;

import app.Main;

/**
 * Greenhouse configuration and records frame
 * 
 * Contains MultiPointDiagram for setting configuration of ventilation and watering
 * and chart with recorded data
 * 
 * @author Lukas Vavra
 *
 */
public class GreenhouseFrame extends JFrame {

	public GreenhouseFrame() {
		super("Správa řídící jednotky");
		this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
		
		this.setLayout(new GridLayout(1, 2));
		add(new WateringPanel());
		add(new VentilationPanel());
		this.pack();
		this.setSize(new Dimension(600, 600));
		this.setLocationRelativeTo(null);
		this.setVisible(true);
	}


	public class WateringPanel extends JPanel {
		
		private JLabel minPrefix = new JLabel("Minimální vlhkost půdy: ");
		private JLabel minPostfix = new JLabel("%");
		private JTextField minField;
		
		private JLabel maxPrefix = new JLabel("Maximální vlhkost půdy: ");
		private JLabel maxPostfix = new JLabel("%");
		private JTextField maxField;

		public WateringPanel() {
			super(new GridBagLayout());
			
			setBorder(BorderFactory.createTitledBorder("Nastavení zavlažování"));

			GridBagConstraints cs = new GridBagConstraints();
			cs.insets = new Insets(10, 10, 10, 10);
			cs.anchor = GridBagConstraints.NORTH;
			cs.fill = GridBagConstraints.BOTH;
			cs.weightx = 1;
			cs.weighty = 1;
			

			cs.gridx = 0;
			cs.gridy = 0;
			cs.gridwidth = 1;
			cs.gridheight = 1;
			this.add(new TimeListPanel("Časy zavlažování", Main.storage.getWateringTimes()), cs);

			JPanel optionPanel = new JPanel(new GridBagLayout());
			optionPanel.setBorder(BorderFactory.createTitledBorder("Automatické zavlažování"));
			cs.gridx = 0;
			cs.gridy = 1;
			cs.gridwidth = 1;
			cs.gridheight = 1;
			this.add(optionPanel, cs);

			// Option Panel
			cs.insets = new Insets(10, 5, 10, 5);
			
			JCheckBox autoctrl = new JCheckBox("Automatické zavlažování");
			autoctrl.addItemListener(new AutoctrlListener());
			cs.gridx = 0;
			cs.gridy = 0;
			cs.gridwidth = GridBagConstraints.REMAINDER;
			cs.gridheight = 1;
			optionPanel.add(autoctrl, cs);
			
			cs.gridx = 0;
			cs.gridy = 1;
			cs.gridwidth = 1;
			cs.gridheight = 1;
			optionPanel.add(minPrefix, cs);
			
			minField = new JTextField(20);
			cs.weightx = 1;
			cs.gridx = 1;
			cs.gridy = 1;
			cs.gridwidth = 1;
			cs.gridheight = 1;
			optionPanel.add(minField, cs);

			cs.weightx = 0;
			cs.gridx = 2;
			cs.gridy = 1;
			cs.gridwidth = 1;
			cs.gridheight = 1;
			optionPanel.add(minPostfix, cs);

			cs.gridx = 0;
			cs.gridy = 2;
			cs.gridwidth = 1;
			cs.gridheight = 1;
			optionPanel.add(maxPrefix, cs);
			
			maxField = new JTextField(20);
			cs.weightx = 1;
			cs.gridx = 1;
			cs.gridy = 2;
			cs.gridwidth = 1;
			cs.gridheight = 1;
			optionPanel.add(maxField, cs);
			
			cs.weightx = 0;
			cs.gridx = 2;
			cs.gridy = 2;
			cs.gridwidth = 1;
			cs.gridheight = 1;
			optionPanel.add(maxPostfix, cs);
			
			setAutoctrlEnabled(false);
		}
		
		private void setAutoctrlEnabled(boolean enabled) {
			minPrefix.setEnabled(enabled);
			minField.setEnabled(enabled);
			minPostfix.setEnabled(enabled);
			maxPrefix.setEnabled(enabled);
			maxField.setEnabled(enabled);
			maxPostfix.setEnabled(enabled);
		}
		
		public class AutoctrlListener implements ItemListener {
			@Override
			public void itemStateChanged(ItemEvent e) {
				if(e.getStateChange() == ItemEvent.SELECTED) {
					setAutoctrlEnabled(true);
				}
				else {
					setAutoctrlEnabled(false);
				}
			}
			
		}

	}

	public class VentilationPanel extends JPanel {
		private JLabel minTPrefix = new JLabel("Minimální teplota: ");
		private JLabel minTPostfix = new JLabel("°C");
		private JTextField minTField;
		
		private JLabel maxTPrefix = new JLabel("Maximální teplota: ");
		private JLabel maxTPostfix = new JLabel("°C");
		private JTextField maxTField;
		
		private JLabel minHPrefix = new JLabel("Minimální vlhkost: ");
		private JLabel minHPostfix = new JLabel("%");
		private JTextField minHField;
		
		private JLabel maxHPrefix = new JLabel("Maximální vlhkost: ");
		private JLabel maxHPostfix = new JLabel("%");
		private JTextField maxHField;



		public VentilationPanel() {
			super(new GridBagLayout());
			
			setBorder(BorderFactory.createTitledBorder("Nastavení ventilace"));

			GridBagConstraints cs = new GridBagConstraints();
			cs.insets = new Insets(10, 10, 10, 10);
			cs.anchor = GridBagConstraints.NORTH;
			cs.fill = GridBagConstraints.BOTH;
			cs.weightx = 1;
			cs.weighty = 1;
			
			cs.gridx = 0;
			cs.gridy = 0;
			cs.gridwidth = 1;
			cs.gridheight = 1;
			this.add(new TimeListPanel("Časy ventilace", Main.storage.getVentilationTimes()), cs);

			
			JPanel optionPanel = new JPanel(new GridBagLayout());
			optionPanel.setBorder(BorderFactory.createTitledBorder("Automatická ventilace"));
			cs.gridx = 0;
			cs.gridy = 1;
			cs.gridwidth = 1;
			cs.gridheight = 1;
			this.add(optionPanel, cs);

			// Option Panel
			cs.insets = new Insets(10, 5, 10, 5);
			
			JCheckBox autoctrl = new JCheckBox("Automatická ventilace");
			autoctrl.addItemListener(new AutoctrlListener());
			cs.gridx = 0;
			cs.gridy = 0;
			cs.gridwidth = GridBagConstraints.REMAINDER;
			cs.gridheight = 1;
			optionPanel.add(autoctrl, cs);
			
			cs.gridx = 0;
			cs.gridy = 1;
			cs.gridwidth = 1;
			cs.gridheight = 1;
			optionPanel.add(maxTPrefix, cs);
			
			maxTField = new JTextField(20);
			cs.weightx = 1;
			cs.gridx = 1;
			cs.gridy = 1;
			cs.gridwidth = 1;
			cs.gridheight = 1;
			optionPanel.add(maxTField, cs);

			cs.weightx = 0;
			cs.gridx = 2;
			cs.gridy = 1;
			cs.gridwidth = 1;
			cs.gridheight = 1;
			optionPanel.add(maxTPostfix, cs);

			cs.gridx = 0;
			cs.gridy = 2;
			cs.gridwidth = 1;
			cs.gridheight = 1;
			optionPanel.add(minTPrefix, cs);
			
			minTField = new JTextField(20);
			cs.weightx = 1;
			cs.gridx = 1;
			cs.gridy = 2;
			cs.gridwidth = 1;
			cs.gridheight = 1;
			optionPanel.add(minTField, cs);
			
			cs.weightx = 0;
			cs.gridx = 2;
			cs.gridy = 2;
			cs.gridwidth = 1;
			cs.gridheight = 1;
			optionPanel.add(minTPostfix, cs);

			cs.gridx = 0;
			cs.gridy = 3;
			cs.gridwidth = 1;
			cs.gridheight = 1;
			optionPanel.add(maxHPrefix, cs);
			
			maxHField = new JTextField(20);
			cs.weightx = 1;
			cs.gridx = 1;
			cs.gridy = 3;
			cs.gridwidth = 1;
			cs.gridheight = 1;
			optionPanel.add(maxHField, cs);

			cs.weightx = 0;
			cs.gridx = 2;
			cs.gridy = 3;
			cs.gridwidth = 1;
			cs.gridheight = 1;
			optionPanel.add(maxHPostfix, cs);

			cs.gridx = 0;
			cs.gridy = 4;
			cs.gridwidth = 1;
			cs.gridheight = 1;
			optionPanel.add(minHPrefix, cs);
			
			minHField = new JTextField(20);
			cs.weightx = 1;
			cs.gridx = 1;
			cs.gridy = 4;
			cs.gridwidth = 1;
			cs.gridheight = 1;
			optionPanel.add(minHField, cs);
			
			cs.weightx = 0;
			cs.gridx = 2;
			cs.gridy = 4;
			cs.gridwidth = 1;
			cs.gridheight = 1;
			optionPanel.add(minHPostfix, cs);

			setAutoctrlEnabled(false);
		}
		
		private void setAutoctrlEnabled(boolean enabled) {
			minTPrefix.setEnabled(enabled);
			minTField.setEnabled(enabled);
			minTPostfix.setEnabled(enabled);
			maxTPrefix.setEnabled(enabled);
			maxTField.setEnabled(enabled);
			maxTPostfix.setEnabled(enabled);
			minHPrefix.setEnabled(enabled);
			minHField.setEnabled(enabled);
			minHPostfix.setEnabled(enabled);
			maxHPrefix.setEnabled(enabled);
			maxHField.setEnabled(enabled);
			maxHPostfix.setEnabled(enabled);

		}
		
		public class AutoctrlListener implements ItemListener {
			@Override
			public void itemStateChanged(ItemEvent e) {
				if(e.getStateChange() == ItemEvent.SELECTED) {
					setAutoctrlEnabled(true);
				}
				else {
					setAutoctrlEnabled(false);
				}
			}
			
		}
	}

	public class TimeListPanel extends JPanel {
		private JList<String> list;
		private DefaultListModel<String> model;

		JSpinner timeSpinner;
		JSpinner delaySpinner;

		public TimeListPanel(String title, String[] data) {
			super(new GridBagLayout());
			setBorder(BorderFactory.createTitledBorder(title));

			model = new DefaultListModel<String>();
			for(String o : data) {
				model.addElement(o);
			}

			list = new JList<>(model);
			list.addKeyListener(new KeyDelete());
			JScrollPane scroll = new JScrollPane(list);
			scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);

			GridBagConstraints cs = new GridBagConstraints();
			cs.insets = new Insets(10, 10, 10, 10);
			cs.fill = GridBagConstraints.BOTH;

			cs.gridx = 0;
			cs.gridy = 0;
			cs.weightx = 0;
			add(new JLabel("Čas spuštění: "), cs);

			timeSpinner = createTimeSpinner();
			cs.gridx = 1;
			cs.gridy = 0;
			cs.weightx = 1;
			add(timeSpinner, cs);

			cs.gridx = 0;
			cs.gridy = 1;
			cs.weightx = 0;
			add(new JLabel("Délka spuštění: "), cs);

			delaySpinner = createDelaySpinner();
			cs.gridx = 1;
			cs.gridy = 1;
			cs.weightx = 1;
			add(delaySpinner, cs);

			JButton addit = new JButton("Přidat");
			addit.addActionListener(new AddItem());
			cs.gridx = 0;
			cs.gridy = 2;
			cs.gridwidth = 2;
			cs.weightx = 1;
			add(addit, cs);

			cs.gridx = 0;
			cs.gridy = 3;
			cs.gridwidth = 2;
			cs.weightx = 1;
			cs.weighty = 1;
			cs.ipady = 100;
			add(scroll, cs);

			JButton remove = new JButton("Odebrat označené");
			remove.addActionListener(new RemoveItem());
			cs.gridx = 0;
			cs.gridy = 4;
			cs.gridwidth = 2;
			cs.weightx = 1;
			cs.weighty = 0;
			cs.ipady = 0;
			add(remove, cs);
		}

		private JSpinner createTimeSpinner() {
			String[] time = new String[144];
			int i = 0;
			for(int h = 0; h < 24; h++)
				for(int m = 0; m < 60; m += 10) {
					time[i] = (h < 10 ? "0".concat(Integer.toString(h)) : Integer.toString(h))
							.concat(":").concat(m == 0 ? "00" : Integer.toString(m));
					i++;
				}

			SpinnerListModel spinmodel = new SpinnerListModel(time);
			JSpinner spinner = new JSpinner(spinmodel);
			return spinner;
		}

		private JSpinner createDelaySpinner() {
			String[] delay = new String[256];
			int i = 0;
			for(int d = 0; d < 1280; d += 5) {
				delay[i] = Integer.toString(d).concat(" s");
				i++;
			}

			SpinnerListModel spinmodel = new SpinnerListModel(delay);
			JSpinner spinner = new JSpinner(spinmodel);
			return spinner;

		}

		private class AddItem implements ActionListener {
			@Override
			public void actionPerformed(ActionEvent e) {
				String time = timeSpinner.getValue().toString();
				String element = time.concat(", ").concat(delaySpinner.getValue().toString());
				String[] t = time.split(":");
				int h = Integer.parseInt(t[0]);
				int m = Integer.parseInt(t[1]);
				
				for(int i = 0; i < model.getSize(); i++) {
					//String[] 
				}
				
				list.ensureIndexIsVisible(model.getSize() - 1);
			}

		}

		private class RemoveItem implements ActionListener {

			@Override
			public void actionPerformed(ActionEvent e) {
				int index = list.getSelectedIndex();
				while(index >= 0) {
					model.remove(index);
					index = list.getSelectedIndex();
				}
			}

		}

		private class KeyDelete implements KeyListener {

			@Override
			public void keyPressed(KeyEvent e) {
				if(e.getKeyCode() == KeyEvent.VK_DELETE) {
					int index = list.getSelectedIndex();
					while(index >= 0) {
						model.remove(index);
						index = list.getSelectedIndex();
					}
				}
			}

			@Override
			public void keyReleased(KeyEvent e) {
				// TODO Automaticky generovaný stub metody

			}

			@Override
			public void keyTyped(KeyEvent e) {
				// TODO Automaticky generovaný stub metody

			}

		}
	}
}
